package com.chen.qhwhiteboardman.video;

import static android.opengl.GLES20.GL_LINEAR;
import static android.opengl.GLES20.GL_LINEAR_MIPMAP_LINEAR;
import static android.opengl.GLES20.GL_TEXTURE_2D;
import static android.opengl.GLES20.GL_TEXTURE_MAG_FILTER;
import static android.opengl.GLES20.GL_TEXTURE_MIN_FILTER;
import static android.opengl.GLES20.glBindTexture;
import static android.opengl.GLES20.glDeleteTextures;
import static android.opengl.GLES20.glGenTextures;
import static android.opengl.GLES20.glGenerateMipmap;
import static android.opengl.GLES20.glTexParameteri;
import static android.opengl.GLUtils.texImage2D;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ColorSpace;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;

import com.chen.qhwhiteboardman.R;

public class QHRecordingPreviewScheduler implements QHRecordingPreviewView.QHRecordingPreviewViewCallback, QHVideoCamera.QHVideoCameraCallback {

    private QHRecordingPreviewView previewV;
    private QHVideoCamera videoCamera;

    private boolean isFirst = true;
    private boolean isSurfaceExsist = false;
    private boolean isStopped = true;
    private int defaultCameraFacingId = Camera.CameraInfo.CAMERA_FACING_BACK;

    private Context context;
    private boolean addWI = true;

    public QHRecordingPreviewScheduler(QHRecordingPreviewView pv, QHVideoCamera vc, Context ctx) {
        isStopped = false;
        previewV = pv;
        videoCamera = vc;
        previewV.setCallback(this);
        videoCamera.setCallback(this);
        context = ctx;
    }

    public void startPreview(final int cameraFacingId) {
        try {
            if (previewV != null) {
                SurfaceHolder holder = previewV.getHolder();
                if (holder != null) {
                    Surface sf = holder.getSurface();
                    if (sf != null) {
                        startPreview(sf, previewV.getWidth(), previewV.getHeight(), cameraFacingId);
                    }
                }
            }
        }
        catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public void stop() {
        isStopped = true;
        if (!isSurfaceExsist) {
            stopPreview();
        }
    }

    // Private

    private void startPreview(Surface sf, int w, int h, final int cameraFacingId) {
        if (isFirst) {
            prepareEGLContext(sf, w, h, cameraFacingId);
            isFirst = false;
        }
        else {
            createWindowSurface(sf);
        }
        isSurfaceExsist = true;
    }

    private void stopPreview() {
        destroyEGLContext();
        isFirst = true;
        isSurfaceExsist = false;
        isStopped = false;
    }

    // API

    /** 切换摄像头, 底层会在返回来调用configCamera, 之后在启动预览 **/
    public native void switchCameraFacing();
    public native void createWindowSurface(Surface surface);
    public native void destroyWindowSurface();
    public native void prepareEGLContext(Surface surface, int width, int height, int cameraFacingId);
    public native void destroyEGLContext();

    // QHRecordingPreviewView.QHRecordingPreviewViewCallback

    @Override
    public void createSurface(Surface surface, int width, int height) {
        startPreview(surface, width, height, defaultCameraFacingId);
    }

    @Override
    public native void resetRenderSize(int width, int height);

    @Override
    public void destroySurface() {
        if (isStopped) {
            stopPreview();
        }
        else {
            destroyWindowSurface();
        }
        isSurfaceExsist = false;
    }

    // QHVideoCamera.QHVideoCameraCallback

    @Override
    public void onPermissionDismiss(String tip){
        Log.i("problem", "onPermissionDismiss : " + tip);
    }
    /**
     * 当Camera捕捉到了新的一帧图像的时候会调用这个方法,因为更新纹理必须要在EGLThread中,
     * 所以配合下updateTexImageFromNative使用
     **/
    @Override
    public native void notifyFrameAvailable();

    // info

    private CameraConfigInfo cfgInfo;
    /** 当底层创建好EGLContext之后，回调回来配置Camera，返回Camera的配置信息，然后在EGLThread线程中回调回来继续做Camera未完的配置以及Preview **/
    public CameraConfigInfo configCameraFromNative(int cameraFacingId) {
        defaultCameraFacingId = cameraFacingId;
        cfgInfo = videoCamera.configCameraFromNative(cameraFacingId);
        return cfgInfo;
    }
    /** 当底层EGLThread创建初纹理之后,设置给Camera **/
    public void startPreviewFromNative(int textureId) {
        if (addWI) {
            createImageTexture();
            addWI = false;
        }
        videoCamera.setCameraPreviewTexture(textureId);
    }
    /** 当底层EGLThread更新纹理的时候调用这个方法 **/
    public void updateTexImageFromNative() {
        videoCamera.updateTexImage();
    }
    /** 释放掉当前的Camera **/
    public void releaseCameraFromNative() {
        videoCamera.releaseCamera();
    }

    void createImageTexture() {
        final Bitmap mOriginalBmp = BitmapFactory.decodeResource(context.getResources(), R.drawable.wb_img);
        int w = mOriginalBmp.getWidth();
        int h = mOriginalBmp.getHeight();
        //ColorSpace s = mOriginalBmp.getColorSpace();
        int[] pixels = new int[w * h];
        mOriginalBmp.getPixels(pixels, 0, w, 0, 0, w, h);
        setImgData(pixels, w, h);
    }

    public native void setImgData(int[] imgData, int w, int h);
}
